package com.bizhibihui.ordermeal.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.bizhibihui.ordermeal.entity.BizAddress;
import com.bizhibihui.ordermeal.entity.BizFood;
import com.bizhibihui.ordermeal.entity.User;
import com.bizhibihui.ordermeal.exception.FoodNotFoundException;
import com.bizhibihui.ordermeal.service.BizAddressService;
import com.bizhibihui.ordermeal.service.BizFoodService;
import com.bizhibihui.ordermeal.service.UserService;
import com.bizhibihui.ordermeal.util.*;
import com.bizhibihui.ordermeal.vo.AddressConditionVo;
import com.bizhibihui.ordermeal.vo.FoodConditionVo;
import com.bizhibihui.ordermeal.vo.base.BaseConditionVo;
import com.bizhibihui.ordermeal.vo.base.ResponseVo;
import com.google.code.kaptcha.Constants;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;

/**
 * 前端页面相关接口
 *
 */
@Slf4j
@Controller
@AllArgsConstructor
public class WebController {

    private static final String THEME_PREFIX = "theme/";

    private final BizFoodService bizFoodService;

    private final UserService userService;

    private final BizAddressService addressService;

    /**
     * 首页
     *
     * @param model
     * @param vo
     * @return
     */
    @GetMapping("/")
    public String index(Model model, FoodConditionVo vo) {
        if (SecurityUtils.getSubject().isAuthenticated()) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            model.addAttribute("user", user);
        }else{
            return "/front/login";
        }
        model.addAttribute("pageUrl", "food/index");
        model.addAttribute("categoryId", "index");
        loadMainPage(model, vo);

        return THEME_PREFIX +"pblog/index";
    }

    @GetMapping("/front/login")
    public String login(Model model) {
        if (SecurityUtils.getSubject().isAuthenticated()) {
            return "redirect:/";
        }
        return "front/login";
    }

    /**
     * 提交登录
     *
     * @param request
     * @param username
     * @param password
     * @param verification
     * @param rememberMe
     * @return
     */
    @PostMapping("/front/login")
    @ResponseBody
    public ResponseVo login(HttpServletRequest request, String username, String password, String verification,
                            @RequestParam(value = "rememberMe", defaultValue = "0") Integer rememberMe) {
        //判断验证码
        String rightCode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (StringUtils.isNoneBlank(verification, rightCode) && StringUtils.equalsIgnoreCase(verification, rightCode)) {
            //验证码通过
        } else {
            log.error("验证码错误。session验证码:{}，收到验证码:{}", rightCode, verification);
            return ResultUtil.error("验证码错误！");
        }
        UsernamePasswordToken token = new UsernamePasswordToken(username, password);
        try {
            token.setRememberMe(1 == rememberMe);
            Subject subject = SecurityUtils.getSubject();
            subject.login(token);
        } catch (LockedAccountException e) {
            token.clear();
            return ResultUtil.error("用户已经被锁定不能登录，请联系管理员！");
        } catch (AuthenticationException e) {
            token.clear();
            return ResultUtil.error("用户名或者密码错误！");
        }
        //更新最后登录时间
        userService.updateLastLoginTime((User) SecurityUtils.getSubject().getPrincipal());
        return ResultUtil.success("登录成功！");
    }

    @GetMapping(value = "/front/register")
    public String register(Model model){
        return "front/register";
    }

    //*提交注册*//*
    @PostMapping("/front/register")
    @ResponseBody
    public ResponseVo register(HttpServletRequest request, User registerUser, String confirmPassword, String verification){
        //判断验证码
        String rightCode = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (StringUtils.isNotBlank(verification) && StringUtils.isNotBlank(rightCode) && verification.equals(rightCode)) {
            //验证码通过
        } else {
            return ResultUtil.error("验证码错误！");
        }
        String username = registerUser.getUsername();
        User user = userService.selectByUsername(username);
        if (null != user) {
            return ResultUtil.error("用户名已存在！");
        }
        String password = registerUser.getPassword();
        //判断两次输入密码是否相等
        if (confirmPassword != null && password != null) {
            if (!confirmPassword.equals(password)) {
                return ResultUtil.error("两次密码不一致！");
            }
        }
        registerUser.setUserId(UUIDUtil.getUniqueIdByUUId());
        registerUser.setStatus(CoreConst.STATUS_VALID);
        Date date = new Date();
        registerUser.setCreateTime(date);
        registerUser.setUpdateTime(date);
        registerUser.setLastLoginTime(date);
        PasswordHelper.encryptPassword(registerUser);
        //注册
        int registerResult = userService.register(registerUser);
        if(registerResult > 0){
            return ResultUtil.success("注册成功！");
        }else {
            return ResultUtil.error("注册失败，请稍后再试！");
        }
    }

    /**
     *
     * @param pageNumber
     * @param vo
     * @param model
     * @return
     */
    @RequestMapping("/food/index/{pageNumber}")
    public String index(@PathVariable("pageNumber") Integer pageNumber, Model model,FoodConditionVo vo) {
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "food/index");
        model.addAttribute("categoryId", "index");
        loadMainPage(model, vo);
        return THEME_PREFIX +"pblog/index";
    }

    /**
     * 分类列表
     *
     * @param categoryId
     * @param model
     * @return
     */
    @GetMapping("/food/category/{categoryId}")
    public String category(@PathVariable("categoryId") Integer categoryId, Model model) {
        FoodConditionVo vo = new FoodConditionVo();
        vo.setCategoryId(categoryId);
        model.addAttribute("pageUrl", "blog/category/" + categoryId);
        model.addAttribute("categoryId", categoryId);
        loadMainPage(model, vo);
        return THEME_PREFIX + "pblog" + "/index";
    }

    @GetMapping("/food/category/{categoryId}/{pageNumber}")
    public String category(@PathVariable("categoryId") Integer categoryId, @PathVariable("pageNumber") Integer pageNumber, Model model) {
        FoodConditionVo vo = new FoodConditionVo();
        vo.setCategoryId(categoryId);
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "blog/category/" + categoryId);
        model.addAttribute("categoryId", categoryId);
        loadMainPage(model, vo);
        return THEME_PREFIX + "pblog" + "/index";
    }


    /**
     * 标签列表
     *
     * @param tagId
     * @param model
     * @return
     */
    @GetMapping("/food/tag/{tagId}")
    public String tag(@PathVariable("tagId") Integer tagId, Model model) {
        FoodConditionVo vo = new FoodConditionVo();
        vo.setTagId(tagId);
        model.addAttribute("pageUrl", "blog/tag/" + tagId);
        loadMainPage(model, vo);
        return THEME_PREFIX + "pblog" + "/index";
    }

    /**
     * 标签列表（分页）
     *
     * @param tagId
     * @param pageNumber
     * @param model
     * @return
     */
    @GetMapping("/food/tag/{tagId}/{pageNumber}")
    public String tag(@PathVariable("tagId") Integer tagId, @PathVariable("pageNumber") Integer pageNumber, Model model) {
        FoodConditionVo vo = new FoodConditionVo();
        vo.setTagId(tagId);
        vo.setPageNumber(pageNumber);
        model.addAttribute("pageUrl", "blog/tag/" + tagId);
        loadMainPage(model, vo);
        return THEME_PREFIX + "pblog" + "/index";
    }

    /**
     * 详情
     *
     * @param model
     * @param foodId
     * @return
     */
    @GetMapping("/food/{foodId}")
    public String article(HttpServletRequest request, Model model, @PathVariable("foodId") Integer foodId) {
        BizFood food = bizFoodService.selectById(foodId);
        if (food == null || CoreConst.STATUS_INVALID.equals(food.getStatus())) {
            throw new FoodNotFoundException();
        }
        model.addAttribute("food", food);
        model.addAttribute("categoryId", food.getCategoryId());
        return THEME_PREFIX + "pblog" + "/article";
    }

    /**
     * 评论
     *
     * @param model
     * @return
     */
    @GetMapping("/food/comment")
    public String comment(Model model) {
        model.addAttribute("categoryId", "comment");
        return THEME_PREFIX + "pblog" + "/comment";
    }

    private void loadMainPage(Model model, FoodConditionVo vo) {
        vo.setStatus(CoreConst.STATUS_VALID);
        IPage<BizFood> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());
        List<BizFood> foodList = bizFoodService.findByCondition(page, vo);
        if (SecurityUtils.getSubject().isAuthenticated()) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            model.addAttribute("user", user);
        }
        model.addAttribute("page", page);
        model.addAttribute("foodList", foodList);

    }

    @GetMapping("/address")
    public String address(Model model, AddressConditionVo vo){
        IPage<BizAddress> page = new Pagination<>(vo.getPageNumber(), vo.getPageSize());
        if (SecurityUtils.getSubject().isAuthenticated()) {
            User user = (User) SecurityUtils.getSubject().getPrincipal();
            model.addAttribute("user", user);
            vo.setUserId(user.getUserId());
        }
        List<BizAddress> addressList = addressService.findByCondition(page, vo);
        model.addAttribute("page", page);
        model.addAttribute("addressList", addressList);

        return "front" + "/address/list";
    }

    @PostMapping("/address/save")
    @ResponseBody
    public ResponseVo saveAddress(BizAddress address){
        Date date = new Date();
        if (address.getId() == null){
            User user = (User)SecurityUtils.getSubject().getPrincipal();
            address.setUserId(user.getUserId());
            address.setCreateTime(date);
        }
        address.setUpdateTime(date);
        boolean i = false;
        if (address.getId() != null){
            i= addressService.updateById(address);
        }else{
            i=addressService.save(address);
        }
        if (i) {
            return ResultUtil.success("保存地址成功");
        } else {
            return ResultUtil.error("保存地址失败");
        }
    }



    @PostMapping("/address/delete")
    @ResponseBody
    public ResponseVo deleteAddress(Integer id){
        boolean i = addressService.removeById(id);
        if (i) {
            return ResultUtil.success("删除地址成功");
        } else {
            return ResultUtil.error("删除地址失败");
        }
    }


    @PostMapping("/address/myAddress")
    @ResponseBody
    public ResponseVo getMyAddress(){
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<BizAddress> bizAddresses = addressService.getMyAddress(user.getUserId());
        return ResultUtil.success("查询成功",bizAddresses);
    }







}
